<?php
namespace Zeke\App;

use Zeke\Zee\App;
use Zeke\Zee as zz;
use Zeke\App\Core\Db\Db;
use Zeke\Net\Http\Server;
use Zeke\Net\Http\Request;
use Zeke\Net\Http\Response;


/**
 * Class Main
 * @package Zeke\App
 *
 * 在父类为子类定义事件处理函数
 * 在子类触发该事件
 *
 * server流转过程：
 *  1: server绑定IoEvent::connect事件，定义connectFunc回调处理函数
 *  2: server对象中的TcpServer绑定IoEvent所有事件，用来触发server的所有IoEvent事件
 *  3: 在TcpServer对象中，loop使用TcpServer绑定addReadStream，定义回调处理函数，结束;
 *
 *  4: loop循环事件是否发生
 *  5: 由 select 或 epoll 触发TcpServer的readStream的回调（生成connect对象，触发server的ioEvent::connect事件）
 *  6: 执行connectFunc回调处理函数，参数为connect对象
 *  本质上server 就是特殊只读的stream，它的addReadStream回调比较固定，accept连接，触发连接事件
 *
 * connect流转过程：
 *  1: 在server的connectFunc回调处理函数中得到connect对象
 *  2: 在connectFunc回调中，connect对象绑定BufferEvent::Data事件，定义DataFunc回调处理函数
 *  3: 在connect对象中，为DuplexResourceStream对象绑定BufferEvent所有事件，用来触发connect对象的BufferEvent的事件（DataFunc回调处理函数）
 *  4: 在DuplexResourceStream对象中，定义WritableResourceStream对象（WritableResourceStream对象内部不使用loop绑定addWriteStream事件）
 *  5: 在DuplexResourceStream对象中，loop使用TcpServer绑定addReadStream，定义回调处理函数，结束;
 *
 *  6: loop循环事件是否发生
 *  7: 由 select 或 epoll 触发DuplexResourceStream对象的readStream的回调（读取socket数据，触发BufferEvent::data事件，即DataFunc回调处理函数）
 *  8: 执行DataFunc回调处理函数，参数为socket读取的数据
 *  9: 在DataFunc回调处理函数中，调用connect对象的write方法
 *  10: 在write方法中，loop使用DuplexResourceStream.WritableResourceStream对象绑定addWriteStream事件，定义回调处理函数，结束;
 *
 *  11: 由 select 或 epoll 触发WritableResourceStream对象的回调（执行fwrite系统写入函数，短连接http则关闭socket）
 *  本质上，connect就是一个读写stream
 */


class Main
{


    /**
     * @var null | App
     */
    private $app = null;


    public function setApp($app)
    {
        $this->app = $app;
    }




    public function main()
    {

        $main = $this;
        $loop = zz\app()->make(\Zeke\Contracts\Io\Loop\LoopContract::class);
        $httpServer = $this->app->make(\Zeke\Contracts\Net\Http\Server\Kernel::class,[
            'requestHandler'=>function(Request $request) use($main){
                $post   = $request->getParsedBody();
                $data   = $main->logic1($post);
                $res    = json_encode($data);
                return new Response(200,[],$res);
            }
        ]);

        $tcpServer = $this->app->make(\Zeke\Contracts\Io\Socket\ServerContract::class,[
            "uri"       => "127.0.0.1:8080",
            "context"   => ['backlog'=>1024]
        ]);
        $httpServer->listen($tcpServer);
        $loop->run();

    }





    /**
     *
     *
     * @param $loop
     *
     *
     * @author <liu.bin@ruaby.com> 2018-08-30 17:56
     */
    public function server2($loop)
    {
        $main = $this;

        $httpServer = new Server(function(Request $request) use($main){
            $post = $request->getParsedBody();
            $data = $main->logic2($post);
            $res = json_encode($data);
            return new Response(200,[],$res);
        });


        $opts = array('backlog'=>1024);
        $tcpServer = new \Zeke\Io\Socket\Server("127.0.0.1:8088",$loop,$opts);
        $httpServer->listen($tcpServer);
    }


    /**
     * 业务逻辑处理
     *
     *
     *
     * @author <liu.bin@ruaby.com> 2018-08-30 17:16
     */
    public function logic1($post=[])
    {

        if(empty($post) || !isset($post['id'])){
            return "undefined id";
        }
        $id = $post['id'];
        $db = Db::instance();
        $sql = "select * from plm_color where id = {$id} limit 10";
        $result = $db->query($sql);
        return $result;
    }



    public function logic2($post)
    {
        $data = ['a','b','c'];
        return $data;
    }

}